<!-- team-avatar-list.vue -->
<template>
	<view class="team-avatar-container">
		<!-- 横向滚动的头像列表 -->
		<scroll-view scroll-x class="avatar-scroll-list" @tap="toggleMemberList" enhanced :bounces="true"
			:show-scrollbar="false" :scroll-anchoring="true">
			<view class="avatar-list">
				<view v-for="(member, index) in displayMembers" :key="member.userId" class="avatar-item"
					:class="{'avatar-item-last': index === displayMembers.length - 1}">
					<image :src="outputBase64(member.image)" class="avatar-image" mode="aspectFill" />
					<view class="avatar-status" :class="{'avatar-status-online': member.online}"></view>
				</view>
				<!-- 显示剩余成员数量 -->
				<view v-if="remainingCount > 0" class="avatar-item more-members" :class="{'avatar-item-last': true}">
					<text class="more-count">+{{ remainingCount }}</text>
				</view>
			</view>
		</scroll-view>

		<!-- 弹出的成员列表 -->
		<uni-popup ref="memberListPopup" type="bottom" background-color="#fff">
			<view class="member-list-popup">
				<view class="popup-header">
					<text class="popup-title">团队成员 ({{ members.length }})</text>
					<view class="close-btn" @tap="closeMemberList">
						<uni-icons type="closeempty" size="20" color="#666"></uni-icons>
					</view>
				</view>
				<scroll-view scroll-y class="member-list" :enhanced="true" :bounces="true" :show-scrollbar="true">
					<view class="search-box">
						<uni-icons type="search" size="16" color="#999"></uni-icons>
						<input type="text" v-model="searchText" placeholder="搜索成员" class="search-input"
							confirm-type="search" />
					</view>

					<view v-for="member in filteredMembers" :key="member.userId" class="member-item"
						:class="{ 'member-item-selected': isSelected(member.userId) }" @tap="handleMemberSelect(member)"
						hover-class="member-item-hover">
						<view class="member-info">
							<view class="avatar-wrapper">
								<image :src="outputBase64(member.image)" class="member-avatar" mode="aspectFill" />
								<view class="member-status" :class="{'member-status-online': member.online}"></view>
							</view>
							<view class="member-details">
								<text class="member-name">{{ member.nickname }}</text>
								<text class="member-role">{{ member.role || '成员' }}</text>
							</view>
						</view>
						<view v-if="selectable" class="checkbox"
							:class="{'checkbox-selected': isSelected(member.userId)}">
							<uni-icons v-if="isSelected(member.userId)" type="checkmarkempty" size="14"
								color="#fff"></uni-icons>
						</view>
					</view>
				</scroll-view>
				<view v-if="selectable && multiSelect" class="popup-footer safe-area-bottom">
					<button class="confirm-btn" @tap="confirmSelection" :disabled="selectedMembers.length === 0"
						:class="{'confirm-btn-active': selectedMembers.length > 0}">
						确认选择 {{ selectedMembers.length ? `(${selectedMembers.length})` : '' }}
					</button>
				</view>
			</view>
		</uni-popup>
	</view>
</template>

<script>
	export default {
		name: 'TeamAvatarList',

		props: {
			members: {
				type: Array,
				required: true,
				validator: function(value) {
					return value.every(member =>
						member.userId !== undefined &&
						member.nickname !== undefined &&
						member.image !== undefined
					)
				},
				default: () => []
			},
			selectable: {
				type: Boolean,
				default: false
			},
			multiSelect: {
				type: Boolean,
				default: false
			},
			maxSelect: {
				type: Number,
				default: 0
			},
			maxDisplayCount: {
				type: Number,
				default: 5
			}
		},

		data() {
			return {
				selectedMembers: [],
				searchText: ''
			}
		},

		computed: {
			displayMembers() {
				return this.members.slice(0, this.maxDisplayCount)
			},
			remainingCount() {
				return Math.max(0, this.members.length - this.maxDisplayCount)
			},
			filteredMembers() {
				if (!this.searchText) return this.members
				const searchLower = this.searchText.toLowerCase()
				return this.members.filter(member =>
					member.nickname.toLowerCase().includes(searchLower)
				)
			}
		},

		methods: {
			outputBase64(base64Url) {
				var base64Data = base64Url;
				base64Data = wx.arrayBufferToBase64(wx.base64ToArrayBuffer(base64Data));
				const base64ImgUrl = "data:image/png;base64," + base64Data;
				return base64ImgUrl;
			},

			toggleMemberList() {
				this.$refs.memberListPopup.open()
			},

			closeMemberList() {
				this.$refs.memberListPopup.close()
				this.searchText = ''
				if (!this.multiSelect) {
					this.selectedMembers = []
				}
			},

			isSelected(userId) {
				return this.selectedMembers.includes(userId)
			},

			handleMemberSelect(member) {
				if (!this.selectable) return

				if (this.multiSelect) {
					const index = this.selectedMembers.indexOf(member.userId)
					if (index > -1) {
						this.selectedMembers.splice(index, 1)
					} else {
						if (this.maxSelect > 0 && this.selectedMembers.length >= this.maxSelect) {
							uni.showToast({
								title: `最多只能选择${this.maxSelect}个成员`,
								icon: 'none',
								duration: 2000
							})
							return
						}
						this.selectedMembers.push(member.userId)
					}
				} else {
					this.selectedMembers = [member.userId]
					const selectedMember = this.members.find(m => m.userId === member.userId)
					this.$emit('select', selectedMember)
					this.closeMemberList()
				}
			},

			confirmSelection() {
				if (this.selectedMembers.length === 0) return

				const selectedMembers = this.members.filter(member =>
					this.selectedMembers.includes(member.userId)
				)
				this.$emit('select', selectedMembers)
				this.closeMemberList()
			}
		}
	}
</script>

<style lang="scss" scoped>
	.team-avatar-container {
		width: 100%;
		max-width: 100%;
		overflow: hidden;
	}

	.avatar-scroll-list {
		width: 100%;
		padding: 16rpx 0;
	}

	.avatar-list {
		display: inline-flex;
		padding: 0 24rpx;
		align-items: center;
	}

	.avatar-item {
		position: relative;
		flex-shrink: 0;
		width: 72rpx;
		height: 72rpx;
		margin-right: 16rpx;
		border-radius: 36rpx;
		background-color: #f5f5f5;
		box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.08);
		transition: transform 0.2s ease;

		&:active {
			transform: scale(0.95);
		}

		&.avatar-item-last {
			margin-right: 0;
		}

		&.more-members {
			background-color: #f0f0f0;
			display: flex;
			align-items: center;
			justify-content: center;
		}
	}

	.avatar-image {
		width: 100%;
		height: 100%;
		border-radius: 36rpx;
	}

	.avatar-status {
		position: absolute;
		right: 0;
		bottom: 0;
		width: 16rpx;
		height: 16rpx;
		border-radius: 50%;
		background-color: #ddd;
		border: 2rpx solid #fff;

		&.avatar-status-online {
			background-color: #52c41a;
		}
	}

	.more-count {
		font-size: 24rpx;
		color: #666;
		font-weight: 500;
	}

	.member-list-popup {
		max-height: 85vh;
		display: flex;
		flex-direction: column;
		border-radius: 24rpx 24rpx 0 0;
		overflow: auto;
	}

	.popup-header {
		flex-shrink: 0;
		display: flex;
		justify-content: space-between;
		align-items: center;
		padding: 24rpx 32rpx;
		background-color: #fff;
		border-bottom: 1rpx solid rgba(0, 0, 0, 0.06);
	}

	.popup-title {
		font-size: 32rpx;
		font-weight: 600;
		color: #333;
	}

	.close-btn {
		padding: 12rpx;
		margin: -12rpx;

		&:active {
			opacity: 0.7;
		}
	}

	.search-box {
		margin: 16rpx 24rpx;
		padding: 16rpx 24rpx;
		background-color: #f5f5f5;
		border-radius: 32rpx;
		display: flex;
		align-items: center;
	}

	.search-input {
		flex: 1;
		margin-left: 12rpx;
		font-size: 28rpx;
		color: #333;

		&::placeholder {
			color: #999;
		}
	}

	.member-list {
		flex: 1;
		background-color: #fff;
		-webkit-overflow-scrolling: touch;
	}

	.member-item {
		display: flex;
		justify-content: space-between;
		align-items: center;
		padding: 20rpx 32rpx;
		background-color: #fff;
		transition: background-color 0.2s ease;

		&.member-item-hover {
			background-color: #f9f9f9;
		}

		&.member-item-selected {
			background-color: rgba(41, 121, 255, 0.05);
		}
	}

	.member-info {
		display: flex;
		align-items: center;
		flex: 1;
	}

	.avatar-wrapper {
		position: relative;
		margin-right: 20rpx;
	}

	.member-avatar {
		width: 80rpx;
		height: 80rpx;
		border-radius: 40rpx;
		background-color: #f5f5f5;
	}

	.member-status {
		position: absolute;
		right: 0;
		bottom: 0;
		width: 16rpx;
		height: 16rpx;
		border-radius: 50%;
		background-color: #ddd;
		border: 2rpx solid #fff;

		&.member-status-online {
			background-color: #52c41a;
		}
	}

	.member-details {
		display: flex;
		flex-direction: column;
		justify-content: center;
	}

	.member-name {
		font-size: 28rpx;
		color: #333;
		font-weight: 500;
		margin-bottom: 4rpx;
	}

	.member-role {
		font-size: 24rpx;
		color: #999;
	}

	.checkbox {
		width: 40rpx;
		height: 40rpx;
		border: 2rpx solid #ddd;
		border-radius: 50%;
		display: flex;
		align-items: center;
		justify-content: center;
		transition: all 0.2s ease;

		&.checkbox-selected {
			background-color: #2979ff;
			border-color: #2979ff;
		}
	}

	.popup-footer {
		flex-shrink: 0;
		padding: 24rpx 32rpx;
		background-color: #fff;
		border-top: 1rpx solid rgba(0, 0, 0, 0.06);
	}

	.confirm-btn {
		width: 100%;
		height: 88rpx;
		line-height: 88rpx;
		text-align: center;
		background-color: #f0f0f0;
		color: #999;
		border-radius: 44rpx;
		font-size: 28rpx;
		font-weight: 500;
		transition: all 0.2s ease;

		&.confirm-btn-active {
			background-color: #2979ff;
			color: #fff;

			&:active {
				opacity: 0.9;
			}
		}
	}

	.safe-area-bottom {
		padding-bottom: calc(24rpx + env(safe-area-inset-bottom));
	}
</style>